/*
 * @CreatDate: 2021-11-24 09:14:12
 * @Describe: ModalForm
 */

import './index.less';
import React, { useRef, useEffect, useState } from 'react';
import { Modal } from 'antd';
import { FullscreenOutlined, FullscreenExitOutlined } from '@ant-design/icons';
import PropTypes from 'prop-types';
import { generateUUID } from '@lycd/utils';
import GForm from '../GForm';
import DragM from './dragm';

const BuildTitle = props => {
  const { title, className, screen, show, topEnd = -100 } = props;

  let modalDom = document
    .querySelector(`.${className}`)
    ?.querySelector('.ant-modal-content');
  useEffect(() => {
    modalDom = document
      .querySelector(`.${className}`)
      ?.querySelector('.ant-modal-content');
  }, []);

  const updateTransform = transformStr => {
    modalDom.style.transform = transformStr;
  };

  return (
    <DragM
      updateTransform={updateTransform}
      screen={screen}
      visible={show}
      topEnd={topEnd}
    >
      <div>{title}</div>
    </DragM>
  );
};

const defaultFormProps = {
  column: 1,
  labelBasicSpan: 5,
  defaultFooterBar: false,
};

const ModalForm = ({
  initialValues,
  formSet,
  loading,
  onValuesChange,
  visible,
  onOk,
  onCancel,
  formProps,
  formRef,
  beforeRender,
  afterRender,
  wrapClassName,
  screen = false,
  title,
  initScreen,
  drag,
  onScreenChange,
  ...restProps
}) => {
  const childFormRef = useRef();
  const [isScreen, setIsScreen] = useState(false);
  const [show, setShow] = useState(false);

  // 动态设置class
  const wrapClassRef = useRef();
  if (!wrapClassRef.current) {
    wrapClassRef.current = `ds${generateUUID()}`;
  }

  const modalProps = {
    visible,
    maskClosable: false,
    onCancel: () => {
      setShow(false);
      setTimeout(() => {
        onCancel && onCancel();
      }, 0);
    },
    cancelText: '取消',
    okText: '保存',
    onOk: () => {
      childFormRef.current.onValidate(onOk);
    },
    ...restProps,
  };

  const fProps = {
    initialValues,
    formSet,
    loading,
    onValuesChange,
    ...defaultFormProps,
    ...formProps,
  };

  useEffect(() => {
    if (visible && formRef && !formRef.current) {
      setTimeout(() => {
        formRef.current = { ...childFormRef.current };
      });
    }
    if (!visible) {
      childFormRef?.current?.resetFields();
      setIsScreen(false);
      resetHeight();
    }
    if (visible && initScreen) {
      setTimeout(() => {
        setIsScreen(true);
        setHeight();
      }, 0);
    }
    setShow(visible);
  }, [visible]);

  const setHeight = () => {
    if (!wrapClassRef.current) return;
    const wrapDom = document.body.querySelector(`.${wrapClassRef.current}`);
    if (wrapDom) {
      const headerHeight = wrapDom.querySelector('.ant-modal-header')
        .offsetHeight;
      const footerHeight = wrapDom.querySelector('.ant-modal-footer')
        ? wrapDom.querySelector('.ant-modal-footer').offsetHeight
        : 0;
      const bodyHeight =
        document.body.clientHeight - headerHeight - footerHeight;
      wrapDom.querySelector('.ant-modal-body').style.height = bodyHeight + 'px';
      wrapDom.querySelector('.ant-modal-content').style.transform =
        'translate(0, 0)';
      onScreenChange && onScreenChange(true, bodyHeight);
    }
  };

  const resetHeight = () => {
    if (!wrapClassRef.current) return;
    const wrapDom = document.body.querySelector(`.${wrapClassRef.current}`);
    if (wrapDom) {
      wrapDom.querySelector('.ant-modal-body').style.height = 'auto';
      if (!drag) {
        wrapDom.querySelector('.ant-modal-content').style.transform =
          'translate(0, 0)';
      }
    }
  };

  // 拖拽功能
  const dragTitle = (
    <BuildTitle
      title={title}
      screen={isScreen}
      show={show}
      className={`${wrapClassRef.current}`}
    />
  );

  return (
    <Modal
      {...modalProps}
      title={drag && visible ? dragTitle : title}
      wrapClassName={
        wrapClassName
          ? `${wrapClassName} ${
              isScreen
                ? `lycd-modal-form-isscreen ${wrapClassRef.current}`
                : `${wrapClassRef.current}`
            }`
          : `${
              isScreen
                ? `lycd-modal-form-isscreen ${wrapClassRef.current}`
                : `${wrapClassRef.current}`
            }`
      }
    >
      {screen && (
        <div className="lycd-modal-form-screen">
          {isScreen ? (
            <FullscreenExitOutlined
              onClick={() => {
                setIsScreen(false);
                resetHeight();
                onScreenChange && onScreenChange(false);
              }}
            />
          ) : (
            <FullscreenOutlined
              onClick={() => {
                setIsScreen(true);
                setHeight();
              }}
            />
          )}
        </div>
      )}
      {beforeRender?.(initialValues)}
      <GForm {...fProps} actionRef={childFormRef} />
      {afterRender?.(initialValues)}
    </Modal>
  );
};

ModalForm.propTypes = {
  /**
   * 表单初始值
   */
  initialValues: PropTypes.object,
  /**
   * 表单的配置项，请参考GForm
   */
  formSet: PropTypes.array,
  /**
   * 请求的加载
   */
  loading: PropTypes.bool,
  /**
   * 表单的值变化监听钩子
   */
  onValuesChange: PropTypes.func,
  /**
   * form内部的一些配置，参考GForm的插件
   */
  formProps: PropTypes.object,

  /**
   * 弹窗显示
   */
  visible: PropTypes.bool,
  /**
   * 保存按钮的回调
   */
  onOk: PropTypes.func,
  /**
   * 关闭按钮的回调
   */
  onCancel: PropTypes.func,

  /**
   * 表单formRef操作
   */
  formRef: PropTypes.object,
};

ModalForm.defaultProps = {
  formProps: {},
};

export default ModalForm;
